package com.restaurant.application.util.wx.templatemsg;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.nebutown.commonunits.utils.DateTimeUtils;
import com.nebutown.commonunits.utils.JacksonUtils;
import com.restaurant.application.util.wx.AccessToken;
import com.restaurant.application.util.wx.WxConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

public class TemplateMsg {

    private final static Logger logger = LoggerFactory.getLogger(TemplateMsg.class);
    private final static String NOW_TOKEN = "accessToken_TemplateMsg";
    private final static Cache<String, String> TOKEN_CACHE = CacheBuilder.newBuilder()
            //设置cache的初始大小为20
            .initialCapacity(20)
            //设置写入并发数为8
            .concurrencyLevel(8)
            //设置cache中的数据存活时间为10秒
            .expireAfterWrite(3600, TimeUnit.SECONDS)
            //构建cache实例
            .build();

    public static TemplateMsgResult sendTemplate(String templateId, String openId, String url, String... keyword) throws Exception {
        TemplateMsgResult templateMsgResult = null;
        Map<String, Map<String, String>> map = TemplateInfo.initInfoMap(templateId, keyword);
        if (Objects.isNull(map)) {
            logger.error("templateId not found:{}", templateId);
        } else {
            TreeMap<String, TreeMap<String, String>> params = new TreeMap<>();
            // 根据具体模板参数组装
            map.forEach((k, v) -> v.forEach((key, value) -> params.put(key, WechatTemplateMsg.item(value, "#0088cc"))));
            WechatTemplateMsg wechatTemplateMsg = new WechatTemplateMsg();
            wechatTemplateMsg.setTemplate_id(templateId);
            wechatTemplateMsg.setTouser(openId);
            wechatTemplateMsg.setUrl(url);
            wechatTemplateMsg.setMiniprogram(WechatTemplateMsg.miniItem(WxConfig.APPID2, url));
            wechatTemplateMsg.setData(params);
            String data = JacksonUtils.obj2json(wechatTemplateMsg);
            templateMsgResult = sendTemplate(getAccessToken(WxConfig.OFF_APPID, WxConfig.OFF_APPSECRET), data);
        }
        return templateMsgResult;
    }

    /**
     * 发送模板消息
     *
     * @param accessToken
     * @param data
     * @return 状态
     */
    private static TemplateMsgResult sendTemplate(String accessToken, String data) throws Exception {
        TemplateMsgResult templateMsgResult = null;
        TreeMap<String, String> params = new TreeMap<>();
        params.put("access_token", accessToken);
        String result = HttpReqUtil.HttpsDefaultExecute(WxConfig.POST_METHOD, WxConfig.SEND_TEMPLATE_MESSAGE,
                params, data, null);
        templateMsgResult = JacksonUtils.json2pojo(result, TemplateMsgResult.class);
        //log.....
        return templateMsgResult;
    }

    public static String getAccessToken(String appId, String secret) {
        String result = null;
        if (Objects.nonNull(TOKEN_CACHE.getIfPresent(NOW_TOKEN))) {
            logger.debug("token from cache at time:{}", DateTimeUtils.getCurrentDateTimeStr());
            return TOKEN_CACHE.getIfPresent(NOW_TOKEN);
        }
        try {
            TreeMap<String, String> map = new TreeMap<>();
            map.put("grant_type", "client_credential");
            map.put("appid", appId);
            map.put("secret", secret);
            String json = HttpReqUtil.HttpDefaultExecute(WxConfig.GET_METHOD, WxConfig.GET_ACCESS_TOKEN_URL, map,
                    "", null);
            logger.debug("getAccessToken result json:{}", json);
            AccessToken accessToken = JacksonUtils.json2pojo(json, AccessToken.class);
            if (accessToken != null) {
                result = accessToken.getAccess_token();
                TOKEN_CACHE.put(NOW_TOKEN, result);
            }
        } catch (Exception e) {
            logger.error("getAccessToken has error:{}", e);
        }
        return result;
    }
}
